package com.niiwoo.civet.user.service.duboo.dataflow;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.niiwoo.civet.account.dto.common.BankCardDTO;
import com.niiwoo.civet.account.service.bankcard.BankCardDubboService;
import com.niiwoo.civet.user.dto.request.ApplicationListRequestDTO;
import com.niiwoo.civet.user.dto.request.DataBackFlowRetryTaskRequestDTO;
import com.niiwoo.civet.user.dto.request.MessageInfoRequestDTO;
import com.niiwoo.civet.user.dto.request.TalkRecordRequestDTO;
import com.niiwoo.civet.user.dto.request.df.BankInfoRequestDTO;
import com.niiwoo.civet.user.dto.request.df.StartAfterLoginRequestDTO;
import com.niiwoo.civet.user.dto.response.IdentityInfoBackflowDTO;
import com.niiwoo.civet.user.service.dataflow.DataBackFlowRetryDubboService;
import com.niiwoo.civet.user.service.dataflow.UserDataBackFlowDubboService;
import com.niiwoo.civet.user.service.local.dataflow.UserDataBackFlowService;
import com.niiwoo.tripod.tiancheng.component.TianchengDataFlowService;
import com.niiwoo.tripod.tiancheng.enums.FunctionCodeEnum;
import com.niiwoo.tripod.tiancheng.request.common.TianchengUapRequest;
import com.niiwoo.tripod.tiancheng.request.df.*;
import com.niiwoo.tripod.tiancheng.response.common.TianchengUapResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer;

/**
 * 天秤数据回流服务
 * Created by lujing on 2017/12/2.
 */
@Slf4j
@Service(version = "1.0.0")
public class UserDataBackFlowDubboServiceImpl implements UserDataBackFlowDubboService {

    public static final int FLOW_DATA_TIMEOUT_SECONDS = 3; // 回流服务超时时间

    @Reference(version = "1.0.0")
    private BankCardDubboService bankCardDubboService;

    @Autowired
    private UserDataBackFlowService userDataBackFlowService;
    @Autowired
    private TianchengDataFlowService tianchengDataFlowService;
    @Reference(version = "1.0.0")
    private DataBackFlowRetryDubboService dataBackFlowRetryDubboService;

    /**
     * 登录后启动数据回流
     *
     * @param startAfterLoginRequestDTO
     */
    @Override
    public void startAfterLoginBackFlow(StartAfterLoginRequestDTO startAfterLoginRequestDTO) {
        String userId = startAfterLoginRequestDTO.getUserId();
        log.info("登录后启动数据回流{}", userId);
        StartAfterLoginRequest request = userDataBackFlowService.startAfterLoginBackFlow(startAfterLoginRequestDTO);
        CompletableFuture<TianchengUapResponse> future = null;
        try {
            future = tianchengDataFlowService.startAfterLogin(request);
            future.whenComplete(dataBackFlowRetry(userId, FunctionCodeEnum.START_AFTER_LOGIN_DATAFLOW, request));
            TianchengUapResponse tianchengUapResponse = future.get(FLOW_DATA_TIMEOUT_SECONDS, TimeUnit.SECONDS);
            log.info("登录后启动数据回流，结果数据：{}", JSON.toJSONString(tianchengUapResponse));
        } catch (Exception e) {
            log.error("登录后启动数据回流失败！异常信息：{}", e.getMessage(), e);
        } finally {
            //取消任务
            future.cancel(true);
        }
    }


    /**
     * 个人信息-身份认证信息回流
     *
     * @param userId
     */
    @Override
    public void identityAuthBackFlow(String userId) {
        log.info("个人信息-身份认证信息回流{}", userId);
        IdentityInfoRequest request = userDataBackFlowService.identityAuthBackFlow(userId);
        CompletableFuture<TianchengUapResponse> future = null;
        try {
            future = tianchengDataFlowService.identityAuth(request);
            future.whenComplete(dataBackFlowRetry(userId, FunctionCodeEnum.IDENTITY_AUTH_DATAFLOW, request));
            TianchengUapResponse tianchengUapResponse = future.get(FLOW_DATA_TIMEOUT_SECONDS, TimeUnit.SECONDS);
            log.info("个人信息-身份认证信息回流，结果数据：{}", JSON.toJSONString(tianchengUapResponse));
        } catch (Exception e) {
            log.error("个人信息-身份认证信息回流失败！异常信息：{}", e.getMessage(), e);
        } finally {
            //取消任务
            future.cancel(true);
        }
    }


    /**
     * 个人信息-银行卡信息回流
     *
     * @param userId
     */
    @Override
    public void bankInfoBackFlow(String userId) {
        log.info("个人信息-银行卡信息回流{}", userId);
        //从账户中心查询银行卡信息
        BankCardDTO bankCardDTO = bankCardDubboService.getUserBankCardInfo(userId);
        BankInfoRequestDTO bankInfoRequestDTO = new BankInfoRequestDTO();
        bankInfoRequestDTO.setUserId(userId.toString());
        bankInfoRequestDTO.setRealName(bankCardDTO.getRealName());
        bankInfoRequestDTO.setBankCardNo(bankCardDTO.getIdCard());
        bankInfoRequestDTO.setBankNo(bankCardDTO.getBankAccountNo());
        bankInfoRequestDTO.setBankType(bankCardDTO.getBankCode());
        bankInfoRequestDTO.setReservedPhone(bankCardDTO.getMobileNo());
        bankInfoRequestDTO.setUpdateTime(bankCardDTO.getUpdateTime().getTime());
        BankInfoRequest request = userDataBackFlowService.bankInfoBackFlow(bankInfoRequestDTO);
        CompletableFuture<TianchengUapResponse> future = null;
        try {
            future = tianchengDataFlowService.bankInfo(request);
            future.whenComplete(dataBackFlowRetry(userId, FunctionCodeEnum.BANK_INFO_DATAFLOW, request));
            TianchengUapResponse tianchengUapResponse = future.get(FLOW_DATA_TIMEOUT_SECONDS, TimeUnit.SECONDS);
            log.info("个人信息-银行卡信息回流，结果数据：{}", JSON.toJSONString(tianchengUapResponse));
        } catch (Exception e) {
            log.error("个人信息-银行卡信息回流失败！异常信息：{}", e.getMessage(), e);
        } finally {
            //取消任务
            future.cancel(true);
        }

    }


    @Override
    public void messageInfo(MessageInfoRequestDTO messageInfoRequest) {
        MessageInfoRequest request = new MessageInfoRequest();
        request.setDeviceId(messageInfoRequest.getDeviceId());
        request.setUserId(messageInfoRequest.getUserId());
        List<MessageInfoRequestDTO.MessageInfo> messageInfoList = messageInfoRequest.getMessageList();
        List<MessageInfoRequest.MessageInfo> messageInfos = new ArrayList<>();
        if (!messageInfoList.isEmpty()) {
            messageInfoList.forEach(p -> {
                MessageInfoRequest.MessageInfo messageInfo = new MessageInfoRequest.MessageInfo();
                messageInfo.setTime(p.getTime());
                messageInfo.setSendOrReceive(p.getSendOrReceive());
                messageInfo.setMobile(p.getMobile());
                messageInfo.setContent(p.getContent());
                messageInfos.add(messageInfo);
            });
        }
        request.setMessageList(messageInfos);
        CompletableFuture<TianchengUapResponse> future = null;
        try {
            future = tianchengDataFlowService.messageInfo(request);
            future.whenComplete(dataBackFlowRetry(messageInfoRequest.getUserId(), FunctionCodeEnum.MESSAGE_INFO, request));
            TianchengUapResponse tianchengUapResponse = future.get(FLOW_DATA_TIMEOUT_SECONDS, TimeUnit.SECONDS);
            log.info("短信息数据回流，结果数据：{}", JSON.toJSONString(tianchengUapResponse));
        } catch (Exception ex) {
            log.error("短信息数据回流失败，异常信息{}", ex);
        } finally {
            //取消任务
            future.cancel(true);
        }
    }

    private BiConsumer<TianchengUapResponse, Throwable> dataBackFlowRetry(String userId, FunctionCodeEnum functionCodeEnum, TianchengUapRequest tianchengUapRequest) {
        return (res, ex) -> {
            try {
                if (ex != null || !"0".equals(res.getStatus())) {
                    DataBackFlowRetryTaskRequestDTO dataBackFlowRetryTaskRequestDTO = new DataBackFlowRetryTaskRequestDTO();
                    dataBackFlowRetryTaskRequestDTO.setUserId(userId);
                    dataBackFlowRetryTaskRequestDTO.setFunctionCode(functionCodeEnum.getBodyFunctionCode());
                    dataBackFlowRetryTaskRequestDTO.setBackflowData(JSON.toJSONString(tianchengUapRequest));
                    dataBackFlowRetryDubboService.saveDataFlowRetryTask(dataBackFlowRetryTaskRequestDTO);
                }
            } catch (Exception e) {
                log.error("dataBackFlowRetry异常，userId={},functionCodeEnum={},tianchengUapRequest={}", userId, JSON.toJSONString(functionCodeEnum), JSON.toJSONString(tianchengUapRequest), e);
            }
        };
    }

    @Override
    public void talkRecord(TalkRecordRequestDTO talkRecordRequestDTO) {
        TalkRecordRequest requestDTO = new TalkRecordRequest();
        requestDTO.setDeviceId(talkRecordRequestDTO.getDeviceId());
        requestDTO.setUserId(talkRecordRequestDTO.getUserId());
        List<TalkRecordRequestDTO.TalkRecord> talkRecordList = talkRecordRequestDTO.getCallRecordsList();
        List<TalkRecordRequest.TalkRecord> talkRecords = new ArrayList<>();
        if (!talkRecordList.isEmpty()) {
            talkRecordList.forEach(p -> {

                TalkRecordRequest.TalkRecord talkRecord = new TalkRecordRequest.TalkRecord();
                talkRecord.setDuration(p.getDuration());
                talkRecord.setMobile(p.getMobile());
                talkRecord.setSendOrReceive(p.getSendOrReceive());
                talkRecord.setTime(p.getTime());
                talkRecords.add(talkRecord);
            });
        }
        requestDTO.setCallRecordsList(talkRecords);
        CompletableFuture<TianchengUapResponse> future = null;
        try {
            future = tianchengDataFlowService.talkRecord(requestDTO);
            future.whenComplete(dataBackFlowRetry(talkRecordRequestDTO.getUserId(), FunctionCodeEnum.TALK_RECORD, requestDTO));
            TianchengUapResponse tianchengUapResponse = future.get(FLOW_DATA_TIMEOUT_SECONDS, TimeUnit.SECONDS);
            log.info("通话记录回流，结果数据：{}", JSON.toJSONString(tianchengUapResponse));
        } catch (Exception ex) {
            log.error("通话记录回流失败，异常信息{}", ex);
        } finally {
            //取消任务
            future.cancel(true);
        }
    }

    @Override
    public void applicationList(ApplicationListRequestDTO applicationListRequestDTO) {
        ApplicationListRequest applicationListRequest = new ApplicationListRequest();
        applicationListRequest.setDeviceId(applicationListRequestDTO.getDeviceId());
        applicationListRequest.setUserId(applicationListRequestDTO.getUserId());
        List<ApplicationListRequestDTO.Application> application = applicationListRequestDTO.getMessageList();
        List<ApplicationListRequest.Application> applicationList = new ArrayList<>();
        if (!application.isEmpty()) {
            application.forEach(p -> {
                ApplicationListRequest.Application appli = new ApplicationListRequest.Application();
                appli.setName(p.getName());
                applicationList.add(appli);
            });
        }
        applicationListRequest.setAppInstallList(applicationList);
        CompletableFuture<TianchengUapResponse> future = null;
        try {
            future = tianchengDataFlowService.applicationList(applicationListRequest);
            future.whenComplete(dataBackFlowRetry(applicationListRequestDTO.getUserId(), FunctionCodeEnum.APPLICATION_LIST, applicationListRequest));
            TianchengUapResponse tianchengUapResponse = future.get(FLOW_DATA_TIMEOUT_SECONDS, TimeUnit.SECONDS);
            log.info("app应用回流，结果数据：{}", JSON.toJSONString(tianchengUapResponse));
        } catch (Exception ex) {
            log.error("app应用回流失败，异常信息{}", ex);
        } finally {
            //取消任务
            future.cancel(true);
        }
    }

    @Override
    public IdentityInfoBackflowDTO getIdentityAuthBackflow(String userId){
        return userDataBackFlowService.getIdentityAuthBackflow(userId);
    }

}
